#include <iostream>
#include <functional>
#include <atomic>
#include <thread>

using namespace std;

class FizzBuzz
{
private:
    int n;
    atomic<int> count;

public:
    FizzBuzz(int n)
    {
        this->n = n;
        count = 1;
    }

    // printFizz() outputs "fizz".
    void fizz(function<void()> printFizz)
    {
        while (count <= n)
        {
            if (count % 3 == 0 && count % 5 != 0)
            {
                printFizz();
                count++;
            }
        }
    }

    // printBuzz() outputs "buzz".
    void buzz(function<void()> printBuzz)
    {
        while (count <= n)
        {
            if (count % 5 == 0 && count % 3 != 0)
            {
                printBuzz();
                count++;
            }
        }
    }

    // printFizzBuzz() outputs "fizzbuzz".
    void fizzbuzz(function<void()> printFizzBuzz)
    {
        while (count <= n)
        {
            if (count % 5 == 0 && count % 3 == 0)
            {
                printFizzBuzz();
                count++;
            }
        }
    }

    // printNumber(x) outputs "x", where x is an integer.
    void number(function<void(int)> printNumber)
    {
        while (count <= n)
        {
            if (count % 5 != 0 && count % 3 != 0)
            {
                printNumber(count);
                count++;
            }
        }
    }
};

int main()
{
    cout << "Code1195" << endl;
    FizzBuzz *fb = new FizzBuzz(15);
    thread t1(&FizzBuzz::fizz, fb, []()
              { cout << "fizz" << endl; });
    thread t2(&FizzBuzz::buzz, fb, []()
              { cout << "buzz" << endl; });
    thread t3(&FizzBuzz::fizzbuzz, fb, []()
              { cout << "fizzbuzz" << endl; });
    thread t4(&FizzBuzz::number, fb, [](int x)
              { cout << (int)x << endl; });
    t1.join();
    t2.join();
    t3.join();
    t4.join();
    return 0;
}